home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: delta / whiteline CD Series - delta.iso / vision / grafics / programm / ximgtool / mfdb_out.c < prev    next >
C/C++ Source or Header  |  1995-11-25  |  4KB  |  129 lines

  1. #include <vdi.h>
  2.  
  3. #include "imgcodec.h"
  4.  
  5. /* Local extension of public image buffer struct for MFDB output. */
  6.  
  7. typedef struct ibuf
  8. {
  9.   IBUFPUB pub;
  10.   char *line_adr;
  11.   long length;
  12.   long src_bwidth;
  13.   long des_bwidth;
  14.   long plane_size;
  15.   void *raster_ptr;
  16.   void (*user_exit)(void);
  17.   short src_planes, des_planes;
  18.   short width, height;
  19.   char data[];
  20. }
  21. IBUF;
  22.  
  23. /* Forward declaration of local function. */
  24.  
  25. static void mfdb_putline(IBUF *ip);
  26.  
  27. /* Initialization function to be used for decoding input into
  28.  * a standard MFDB (without dithering, but in arbitrary color
  29.  * index plane mode).
  30.  * Returns a zero pointer if user_malloc failes.
  31.  * Otherwise the returned pointer has to be freed after
  32.  * processing by the 'complement' of user_malloc.
  33.  *
  34.  * NOTE: The MFDB-struct must be prefilled with valid entries.
  35.  * The image memory referenced by fd_addr is assumed to be
  36.  * prefilled with zero.
  37.  * The fd_w, fd_h, and fd_wdwidth entries are assumed to be equal
  38.  * to or higher than the input_header values.
  39.  * The fd_nplanes, however, does NOT need to match the input planes,
  40.  * it may rather match the screen mode (color index mode assumed).
  41.  *
  42.  * The code provided here is thought as a base for applications
  43.  * that need screen representation of image data. Advanced
  44.  * applications must extend the code (dithering, direct color
  45.  * mode support).
  46.  */
  47.  
  48. IBUFPUB *mfdb_output_init(IMG_HEADER *input_header, MFDB *mfdb,
  49.               void *(*user_malloc)(long size),
  50.               void (*user_exit)(void))
  51. {
  52.   long src_bwidth, des_bwidth, line_len, plane_size;
  53.   IBUF *image;
  54.  
  55.   src_bwidth = (input_header->sl_width + 7) >> 3;
  56.   des_bwidth = mfdb->fd_wdwidth << 1;
  57.   line_len = src_bwidth * input_header->planes;
  58.   plane_size = des_bwidth * mfdb->fd_h;
  59.   image =
  60.     (*user_malloc)(sizeof(IBUF) + line_len + input_header->pat_run);
  61.   if (image)
  62.   {
  63.     image->line_adr = image->pub.pbuf = image->data;
  64.     image->pub.pat_buf = image->data + line_len;
  65.     image->pub.bytes_left = line_len;
  66.     image->length = line_len;
  67.     image->src_bwidth = src_bwidth;
  68.     image->des_bwidth = des_bwidth;
  69.     image->plane_size = plane_size;
  70.     image->pub.pat_run = input_header->pat_run;
  71.     image->src_planes = input_header->planes;
  72.     image->des_planes = mfdb->fd_nplanes;
  73.     image->width = input_header->sl_width;
  74.     image->height = input_header->sl_height;
  75.     image->raster_ptr = mfdb->fd_addr;
  76.     image->user_exit = user_exit;
  77.     image->pub.vrc = 1;
  78.     image->pub.put_line = (void (*)(IBUFPUB *))mfdb_putline;
  79.   }
  80.   return &image->pub;
  81. }
  82.  
  83. static void mfdb_putline(IBUF *ip)
  84. {
  85.   short mask, plane, src_planes, des_planes;
  86.   char *raster_ptr, *line_ptr, *line_buf;
  87.   long i, plane_size;
  88.  
  89.   raster_ptr = ip->raster_ptr; plane_size = ip->plane_size;
  90.   src_planes = ip->src_planes; des_planes = ip->des_planes;
  91.   do
  92.   { i = ip->src_bwidth; line_buf = ip->line_adr;
  93.     loop: line_ptr = raster_ptr; plane = des_planes;
  94.     for (;;)
  95.     {
  96.       if (i & 1L)
  97.     do *line_ptr++ |= *line_buf++; while (--i);
  98.       else
  99.     do *((short *)line_ptr)++ |= *((short *)line_buf)++;
  100.     while (i -= 2);
  101.       if (line_buf >= ip->pub.pbuf) break;
  102.       i = ip->src_bwidth;
  103.       if (--plane <= 0) goto loop;
  104.       line_ptr -= i; line_ptr += plane_size;
  105.     }
  106.     if (src_planes >= des_planes) raster_ptr += ip->des_bwidth;
  107.     else
  108.     {
  109.       i = ip->des_bwidth;
  110.       do
  111.       { plane = 1;
  112.     line_ptr = raster_ptr; mask = *((short *)raster_ptr)++;
  113.     do
  114.     { line_ptr += plane_size;
  115.       if (plane < src_planes) mask &= *(short *)line_ptr;
  116.       else *(short *)line_ptr = mask;
  117.     }
  118.     while (++plane < des_planes);
  119.       }
  120.       while (i -= 2);
  121.     }
  122.     if (--ip->height <= 0) (*ip->user_exit)();
  123.   }
  124.   while (--ip->pub.vrc);
  125.   ip->pub.vrc++;
  126.   ip->raster_ptr = raster_ptr;
  127.   ip->pub.pbuf = ip->line_adr; ip->pub.bytes_left = ip->length;
  128. }
  129.